package com.a51integrated.sfs2x;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.Iterator;

import com.smartfoxserver.v2.db.IDBManager;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;
import com.smartfoxserver.v2.extensions.ExtensionLogLevel;

public class EnterSessionRequestHandler extends BaseClientRequestHandler {

	@Override
	public void handleClientRequest(User player, ISFSObject params) {
		// TODO Auto-generated method stub

		Room last_room = player.getLastJoinedRoom();
		if (last_room != null)
		{			
			// Get password from DB.
			IDBManager dbManager = getParentExtension().getParentZone().getDBManager();
			Connection connection;
			try
			{
				// Grab a connection from the DBManager connection pool.
				connection = dbManager.getConnection();

				String gamename = params.getUtfString("gamename");
				
				// 0) Check whether the desired session exists.
				PreparedStatement stmt = connection.prepareStatement("SELECT COUNT(names) FROM games WHERE names=?");
				stmt.setString(1, gamename);
				ResultSet res = stmt.executeQuery();
				
				// Verify that something was returned.
				if (!res.first())
				{
					trace(ExtensionLogLevel.WARN, "SQL Empty Resultset");
					connection.close();
					return;
				}
				
				// If no valid games have been found, don't join anything and tell the user this.
				if (res.getInt(1) <= 0)
				{
					ISFSObject response = new SFSObject();
					response.putBool("accepted", false);
					response.putUtfString("reason", "Requested session not found");

					// Send the data back to the user.
					send("entersession", response, player);
					
					connection.close();
					return;
				}
				
				// 1) Count the number of taken player spots for the the desired session.
				stmt = connection.prepareStatement("SELECT numconnected FROM games WHERE names=?");
				stmt.setString(1, gamename);
				res = stmt.executeQuery();
				
				// Verify that something was returned.
				if (!res.first())
				{
					trace(ExtensionLogLevel.WARN, "SQL Empty Resultset");
					connection.close();
					return;
				}
				
				// 2) If that number if less than the maximum number of players per session (4), continue going, otherwise return a response
				//    that tells the player that he can't join the session anymore.
				int connectedPlayers = res.getInt(1);
				if (connectedPlayers >= 4)	// The number here is the maximum allowed number of users per session.
				{
					ISFSObject response = new SFSObject();
					response.putBool("accepted", false);
					response.putUtfString("reason", "Requested session is full");

					// Send the data back to the user.
					send("entersession", response, player);
					
					connection.close();
					return;
				}
								
				// 3) At this point, the user should be able to join the requested session. Therefore the user may now be added to the session's
				//    player list in the table. The number of connected players for the session must also be updated.
				stmt = connection.prepareStatement( "UPDATE games SET player" + connectedPlayers + "=? WHERE player" + connectedPlayers + "='' AND names=?;" );
				// + "UPDATE games SET numconnected=(numconnected + 1) WHERE names=?"
				stmt.setString(1, player.getName());
				stmt.setString(2, gamename);
				//stmt.setString(3, gamename);
				boolean boolres = stmt.execute();
				boolres = (stmt.getUpdateCount() >= 1);
				
				if (boolres)
				{
					stmt = connection.prepareStatement( "UPDATE games SET numconnected=(numconnected + 1) WHERE names=?" );
					stmt.setString(1, gamename);
					stmt.execute();
					
					// Now update the player table for the session.
					stmt = connection.prepareStatement("INSERT INTO `game_" + gamename + "_players`(`player`, `points`) VALUES('" + player.getName() + "', 0);");
					stmt.execute();
				}

				// Send query in correct format back to the user.
				ISFSObject response = new SFSObject();
				response.putBool("accepted", boolres);
				response.putUtfString("reason", (boolres)?("Cause you're awesome"):("Undefined - (Player already exists in session?)"));	// Ensure there's a reason, might be accessed by a client.
				response.putInt("spawnindex", connectedPlayers);	// This indicates which of the available spawn points the user must choose.
																	// The actual locations of these spawn points are stored client-side.
				

				// Send the data back to the user.
				send("entersession", response, player);
				
				// Now send all clients an update so that they also know that a new user entered the session and can add him to the their list of players.
				response = new SFSObject();
				response.putUtfString("newusername", player.getName());
				response.putInt("spawnindex", connectedPlayers);
				
				// Obtain a list of all players in the room.
				List<User> playerlist = player.getLastJoinedRoom().getPlayersList();
				List<String> playerlist_in_game = new ArrayList<String>();
				
				// Now construct a list with the names of all connected players in the game.
				for (int i = 0; i < 4; ++i)
				{
					stmt = connection.prepareStatement("SELECT `player" + i + "` FROM `games`");
					res = stmt.executeQuery();
					
					String str = res.getString("player" + i); 
					if (str != "")
					{
						playerlist_in_game.add(str);
					}
				}
				
				// Now send a request to each player that is in the same game.
								
				send("newplayer", response, playerlist);
				

				
				// Return connection to the DBMananger connection pool.
				connection.close();
			}
			catch(SQLException e)
			{
				trace(ExtensionLogLevel.WARN, "SQL Failed: " + e.toString());
			}
		}
		else
		{
			trace("No valid room found for user request.");
		}
	}

}
